﻿using System;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Globalization;
using Peter.Common;
using Peter.Sdw.Data;
using Peter.Sdw.Properties;

namespace Peter.Sdw.Logic
{
   /// <summary>
   /// Represents a love between two lights.
   /// </summary>
   public class LoveModel : ViewModelBase, IDisposable
   {
      private bool m_IsLoading;
      private LoveType m_LoveType;
      private readonly ObservableCollection <TruthModel> m_Truths;

      /// <summary>
      /// Initializes some love.
      /// </summary>
      public LoveModel ()
      {
         this.m_Truths = new ObservableCollection<TruthModel> ();
         WebQueue.Instance.WebGetComplete += this.OnGetCompleted;
         WebQueue.Instance.WebPostComplete += this.OnPostCompleted;
      }

      /// <summary>
      /// Gets or Sets the id.
      /// </summary>
      public int Id { get; set; }

      /// <summary>
      /// Gets or Sets the type of love.
      /// </summary>
      public LoveType LoveType
      {
         get { return this.m_LoveType; }
         set
         {
            this.m_LoveType = value;
            this.RaisePropertyChanged ("LoveType");
            this.Edit ();
         }
      }

      /// <summary>
      /// Gets or Sets the parent.
      /// </summary>
      public LightModel Parent { get; set; }

      /// <summary>
      /// Gets or Sets the child light's id.
      /// </summary>
      public int ChildId { get; set; }

      /// <summary>
      /// Gets or Sets the child light's name.
      /// </summary>
      public string ChildName { get; set; }

      /// <summary>
      /// Gets or Sets if it is ok to send any updates to the server.
      /// </summary>
      public bool OkToUpdate { get; set; }

      /// <summary>
      /// Gets or Sets if we are loading data.
      /// </summary>
      public bool IsLoading
      {
         get { return this.m_IsLoading; }
         set
         {
            this.m_IsLoading = value;
            this.RaisePropertyChanged ("IsLoading");
         }
      }

      /// <summary>
      /// Gets the collection of truths.
      /// </summary>
      public ObservableCollection <TruthModel> Truths { get { return this.m_Truths; } }

      /// <summary>
      /// Gets the truths for this bit of love.
      /// </summary>
      public void GetTruth ()
      {
         if (this.Id > 0) {
            this.IsLoading = true;
            this.Truths.Clear ();
            WebQueue.Instance.Get (string.Format (Constants.URL_GET_TRUTH, this.Id));
         }
      }

      /// <summary>
      /// Posts edit data to the server.
      /// </summary>
      private void Edit ()
      {
         if (!this.OkToUpdate) return;
         var parameters = new NameValueCollection {
            {Constants.REQUEST_TOKEN, WebQueue.Instance.RequestToken},
            {"id", this.Id.ToString (CultureInfo.InvariantCulture)},
            {"type", this.LoveType.Id.ToString (CultureInfo.InvariantCulture)}
         };
         WebQueue.Instance.Post (Constants.URL_EDIT_LOVE, parameters);
      }

      /// <summary>
      /// Occurs when a web get request is completed.
      /// </summary>
      /// <param name="sender">WebQueue.</param>
      /// <param name="e">WebRequestEventArgs</param>
      private void OnGetCompleted (object sender, WebRequestEventArgs e)
      {
         if (e.Url == string.Format (Constants.URL_GET_TRUTH, this.Id)) {
            if (e.Response.status == Constants.SUCCESS) {
               foreach (var truth in e.Response.truths) {
                  this.Truths.Add (new TruthModel {
                     Id = truth.id,
                     Parent = this
                  });
               }
               foreach (var truth in this.Truths) {
                  truth.OkToUpdate = true;
               }
            }
         }
      }

      /// <summary>
      /// Occurs when a web post request is completed.
      /// </summary>
      /// <param name="sender">WebQueue.</param>
      /// <param name="e">WebRequestEventArgs</param>
      private void OnPostCompleted (object sender, WebRequestEventArgs e)
      {
         try {
            if (e.Url == Constants.URL_CREATE_LOVE) {
               if (e.Response.status == Constants.SUCCESS) {
                  Console.WriteLine (@"{0} - {1}", e.Url, Resources.Create_successful);
                  this.Id = e.Response.id;
               }
            } else if (e.Url == Constants.URL_EDIT_LOVE) {
               if (e.Response.status == Constants.SUCCESS)
                  Console.WriteLine (@"{0} - {1}", e.Url, Resources.Edit_successful);
            }
         } catch (Exception ex) {
            Console.WriteLine (ex.Message);
         }
      }

      public void Dispose ()
      {
         WebQueue.Instance.WebGetComplete -= this.OnGetCompleted;
         WebQueue.Instance.WebPostComplete -= this.OnPostCompleted;
      }
   }
}
